﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Moq;
using MyBiz.Core;
using MyBiz.Core.Products;

namespace Test.Core
{
    public class Product1 : IProduct
    {
        public string Id { get; private set; }
        public string Name { get; private set; }
        public IProductCategory Category { get { return ProductFactory.GetCategory1(); } }
        public Money Cost { get; set; }
        public Money Price { get; set; }
        public double Weight { get; set; }
        public double Count { get; set; }

        public Product1()
        {
            Id = "1";
            Name = "prod 1";
            Cost = 10;
            Count = 1;
            Price = 15;
        }

        public IProduct Clone(double count)
        {
            return new Product1
            {
                Cost = this.Cost,
                Count = count,
                
                Weight = this.Weight
            };
        }
    }

    public class Product2 : IProduct
    {
        public string Id { get; private set; }
        public string Name { get; private set; }
        public IProductCategory Category { get { return ProductFactory.GetCategory2(); } }
        public Money Cost { get; set; }
        public Money Price { get; set; }
        public double Weight { get; set; }
        public double Count { get; set; }

        public Product2()
        {
            Id = "2";
            Name = "prod 2";
            Cost = 20;
            Count = 1;
            Price = 25;
        }

        public IProduct Clone(double count)
        {
            return new Product2
            {
                Cost = this.Cost,
                Count = count,
               
                Weight = this.Weight
            };
        }
    }

    public class Product3 : IProduct
    {
        public string Id { get; private set; }
        public string Name { get; private set; }
        public IProductCategory Category { get { return ProductFactory.GetCategory2(); } }
        public Money Cost { get; set; }
        public Money Price { get; set; }
        public double Weight { get; set; }
        public double Count { get; set; }

        public Product3()
        {
            Id = "3";
            Name = "prod 3";
            Cost = 30;
            Count = 1;
            Price = 35;

        }

        public IProduct Clone(double count)
        {
            return new Product3
            {
                Cost = this.Cost,
                Count = count,
                
                Weight = this.Weight
            };
        }
    }

    public static class ProductFactory
    {
        static Dictionary<IProductCategory, IProduct[]> _products = new Dictionary<IProductCategory, IProduct[]>();

        static readonly Mock<IProductCategory>[] Pc = new Mock<IProductCategory>[3];

        public static IProductCategory GetCategory1()
        {
            if (Pc[0] == null)
            {
                Pc[0] = new Mock<IProductCategory>();
                Pc[0].SetupGet(p => p.Id).Returns("category 1");
            }

            return Pc[0].Object;
        }

        public static IProductCategory GetCategory2()
        {
            if (Pc[1] == null)
            {
                Pc[1] = new Mock<IProductCategory>();
                Pc[1].SetupGet(p => p.Id).Returns("category 2");
            }
            return Pc[1].Object;
        }

        public static IProductCategory GetCategory3()
        {
            if (Pc[2] == null)
            {
                Pc[2] = new Mock<IProductCategory>();
                Pc[2].SetupGet(p => p.Id).Returns("category 3");
            }
            return Pc[2].Object;
        }

        public static IProduct GetProduct1Category(int i)
        {
            if (!_products.ContainsKey(GetCategory1()))
                _products.Add(GetCategory1(), new IProduct[10]);

            var prod = _products[GetCategory1()];

            if (prod[i] == null)
            
                prod[i] = new Product1();

            return prod[i];
        }

        public static IProduct GetProduct2Category(int i)
        {
            if (!_products.ContainsKey(GetCategory2()))
                _products.Add(GetCategory2(), new IProduct[10]);

            var prod = _products[GetCategory2()];

            if (prod[i] == null)
                prod[i] = new Product2();

            return prod[i];
        }

        public static IProduct GetProduct3Category(int i)
        {
            if (!_products.ContainsKey(GetCategory3()))
                _products.Add(GetCategory3(), new IProduct[10]);

            var prod = _products[GetCategory3()];

            if (prod[i] == null)
                prod[i] = new Product3();

            return prod[i];
        }

    }
}
